package com.witmore.neutron.ai.web.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.witmore.neutron.ai.db.entity.AgentDO;
import com.witmore.neutron.ai.db.entity.AgentPluginDO;
import com.witmore.neutron.ai.db.entity.PluginDO;
import com.witmore.neutron.ai.db.entity.PluginGroupDO;
import com.witmore.neutron.ai.db.mapper.AgentMapper;
import com.witmore.neutron.ai.db.mapper.AgentPluginMapper;
import com.witmore.neutron.ai.db.mapper.PluginMapper;
import com.witmore.neutron.ai.db.mapper.PluginGroupMapper;
import com.witmore.neutron.ai.web.controller.bo.PluginBindRequest;
import com.witmore.neutron.ai.web.controller.vo.PluginVO;
import com.witmore.neutron.ai.web.controller.vo.PluginGroupVO;
import com.witmore.neutron.ai.web.service.PluginService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 插件服务实现类
 *
 * @author 豆子高
 * @since 2025-01-16
 */
@Slf4j
@Service
public class PluginServiceImpl implements PluginService {

    @Autowired
    private PluginMapper pluginMapper;

    @Autowired
    private PluginGroupMapper pluginGroupMapper;

    @Autowired
    private AgentPluginMapper agentPluginMapper;

    @Autowired
    private AgentMapper agentMapper;

    @Override
    public List<PluginGroupVO> getAvailablePluginGroups(Integer agentId) {
        // 获取所有启用的插件组
        List<PluginGroupDO> allPluginGroups = pluginGroupMapper.selectList(
            new LambdaQueryWrapper<PluginGroupDO>()
                .eq(PluginGroupDO::getEnabled, 1)
                .orderByAsc(PluginGroupDO::getGroupName)
        );
        
        // 获取已绑定的插件组ID集合
        List<AgentPluginDO> boundPluginGroups = agentPluginMapper.selectList(
            new LambdaQueryWrapper<AgentPluginDO>()
                .eq(AgentPluginDO::getAgentId, agentId)
        );
        Map<Integer, AgentPluginDO> boundPluginGroupMap = boundPluginGroups.stream()
            .collect(Collectors.toMap(AgentPluginDO::getPluginGroupId, p -> p));
        
        // 转换为VO
        List<PluginGroupVO> result = new ArrayList<>();
        for (PluginGroupDO pluginGroup : allPluginGroups) {
            PluginGroupVO vo = new PluginGroupVO();
            BeanUtils.copyProperties(pluginGroup, vo);
            
            // 设置类型名称
            vo.setGroupTypeName(getPluginGroupTypeName(pluginGroup.getGroupType()));
            
            // 设置绑定状态
            AgentPluginDO boundPluginGroup = boundPluginGroupMap.get(pluginGroup.getId());
            vo.setIsBound(boundPluginGroup != null);
            if (boundPluginGroup != null) {
                vo.setPriority(boundPluginGroup.getPriority());
            }
            
            // 获取插件组下的插件列表
            List<PluginDO> groupPlugins = pluginMapper.selectList(
                new LambdaQueryWrapper<PluginDO>()
                    .eq(PluginDO::getGroupCode, pluginGroup.getGroupCode())
                    .eq(PluginDO::getEnabled, 1)
                    .orderByAsc(PluginDO::getSortOrder)
            );
            
            List<PluginVO> pluginVOs = new ArrayList<>();
            for (PluginDO plugin : groupPlugins) {
                PluginVO pluginVO = new PluginVO();
                BeanUtils.copyProperties(plugin, pluginVO);
                pluginVO.setPluginTypeName(getPluginTypeName(plugin.getPluginType()));
                pluginVO.setPluginCategoryName(getPluginCategoryName(plugin.getPluginCategory()));
                pluginVOs.add(pluginVO);
            }
            vo.setPlugins(pluginVOs);
            
            result.add(vo);
        }
        
        return result;
    }

    @Override
    public List<PluginGroupVO> getAgentPluginGroups(Integer agentId) {
        // 获取智能体已绑定的插件组关联关系
        List<AgentPluginDO> agentPluginGroups = agentPluginMapper.selectList(
            new LambdaQueryWrapper<AgentPluginDO>()
                .eq(AgentPluginDO::getAgentId, agentId)
                .orderByAsc(AgentPluginDO::getPriority)
        );
        
        if (agentPluginGroups.isEmpty()) {
            return new ArrayList<>();
        }
        
        // 获取插件组详情
        List<Integer> pluginGroupIds = agentPluginGroups.stream()
            .map(AgentPluginDO::getPluginGroupId)
            .collect(Collectors.toList());
            
        List<PluginGroupDO> pluginGroups = pluginGroupMapper.selectBatchIds(pluginGroupIds);
        Map<Integer, PluginGroupDO> pluginGroupMap = pluginGroups.stream()
            .collect(Collectors.toMap(PluginGroupDO::getId, p -> p));
        
        // 转换为VO
        List<PluginGroupVO> result = new ArrayList<>();
        for (AgentPluginDO agentPluginGroup : agentPluginGroups) {
            PluginGroupDO pluginGroup = pluginGroupMap.get(agentPluginGroup.getPluginGroupId());
            if (pluginGroup == null) {
                continue;
            }
            
            PluginGroupVO vo = new PluginGroupVO();
            BeanUtils.copyProperties(pluginGroup, vo);
            vo.setGroupTypeName(getPluginGroupTypeName(pluginGroup.getGroupType()));
            vo.setIsBound(true);
            vo.setPriority(agentPluginGroup.getPriority());
            
            // 获取插件组下的插件列表
            List<PluginDO> groupPlugins = pluginMapper.selectList(
                new LambdaQueryWrapper<PluginDO>()
                    .eq(PluginDO::getGroupCode, pluginGroup.getGroupCode())
                    .eq(PluginDO::getEnabled, 1)
                    .orderByAsc(PluginDO::getSortOrder)
            );
            
            List<PluginVO> pluginVOs = new ArrayList<>();
            for (PluginDO plugin : groupPlugins) {
                PluginVO pluginVO = new PluginVO();
                BeanUtils.copyProperties(plugin, pluginVO);
                pluginVO.setPluginTypeName(getPluginTypeName(plugin.getPluginType()));
                pluginVO.setPluginCategoryName(getPluginCategoryName(plugin.getPluginCategory()));
                pluginVOs.add(pluginVO);
            }
            vo.setPlugins(pluginVOs);
            
            result.add(vo);
        }
        
        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean bindPluginGroup(PluginBindRequest request) {
        try {
            // 检查插件组是否存在
            PluginGroupDO pluginGroup = pluginGroupMapper.selectById(request.getPluginGroupId());
            if (pluginGroup == null) {
                log.error("插件组不存在: {}", request.getPluginGroupId());
                return false;
            }
            
            // 检查智能体是否存在
            AgentDO agent = agentMapper.selectById(request.getAgentId());
            if (agent == null) {
                log.error("智能体不存在: {}", request.getAgentId());
                return false;
            }
            
            // 检查是否已经绑定
            AgentPluginDO existBinding = agentPluginMapper.selectOne(
                new LambdaQueryWrapper<AgentPluginDO>()
                    .eq(AgentPluginDO::getAgentId, request.getAgentId())
                    .eq(AgentPluginDO::getPluginGroupId, request.getPluginGroupId())
            );
            
            if (existBinding != null) {
                log.warn("插件组已绑定到智能体: agentId={}, pluginGroupId={}", request.getAgentId(), request.getPluginGroupId());
                return false;
            }
            
            // 创建绑定关系
            AgentPluginDO agentPlugin = new AgentPluginDO();
            agentPlugin.setAgentId(request.getAgentId());
            agentPlugin.setAgentCode(StringUtils.hasText(request.getAgentCode()) ? request.getAgentCode() : agent.getAgentCode());
            agentPlugin.setPluginGroupId(request.getPluginGroupId());
            agentPlugin.setGroupCode(StringUtils.hasText(request.getGroupCode()) ? request.getGroupCode() : pluginGroup.getGroupCode());
            agentPlugin.setPriority(request.getPriority() != null ? request.getPriority() : 0);
            agentPlugin.setEnabled(request.getEnabled() != null ? request.getEnabled() : 1);
            agentPlugin.setCreateTime(LocalDateTime.now());
            agentPlugin.setUpdateTime(LocalDateTime.now());
            
            int result = agentPluginMapper.insert(agentPlugin);
            
            log.info("插件组绑定成功: agentId={}, pluginGroupId={}, result={}", request.getAgentId(), request.getPluginGroupId(), result);
            return result > 0;
            
        } catch (Exception e) {
            log.error("插件组绑定失败: agentId={}, pluginGroupId={}", request.getAgentId(), request.getPluginGroupId(), e);
            throw e;
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean unbindPluginGroup(Integer agentId, Integer pluginGroupId) {
        try {
            int result = agentPluginMapper.delete(
                new LambdaQueryWrapper<AgentPluginDO>()
                    .eq(AgentPluginDO::getAgentId, agentId)
                    .eq(AgentPluginDO::getPluginGroupId, pluginGroupId)
            );
            
            log.info("插件组解绑成功: agentId={}, pluginGroupId={}, result={}", agentId, pluginGroupId, result);
            return result > 0;
            
        } catch (Exception e) {
            log.error("插件组解绑失败: agentId={}, pluginGroupId={}", agentId, pluginGroupId, e);
            throw e;
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updatePluginGroupBinding(PluginBindRequest request) {
        try {
            AgentPluginDO agentPlugin = agentPluginMapper.selectOne(
                new LambdaQueryWrapper<AgentPluginDO>()
                    .eq(AgentPluginDO::getAgentId, request.getAgentId())
                    .eq(AgentPluginDO::getPluginGroupId, request.getPluginGroupId())
            );
            
            if (agentPlugin == null) {
                log.error("插件组绑定关系不存在: agentId={}, pluginGroupId={}", request.getAgentId(), request.getPluginGroupId());
                return false;
            }
            
            // 更新绑定配置
            if (request.getPriority() != null) {
                agentPlugin.setPriority(request.getPriority());
            }
            if (request.getEnabled() != null) {
                agentPlugin.setEnabled(request.getEnabled());
            }
            agentPlugin.setUpdateTime(LocalDateTime.now());
            
            int result = agentPluginMapper.updateById(agentPlugin);
            
            log.info("插件组绑定更新成功: agentId={}, pluginGroupId={}, result={}", request.getAgentId(), request.getPluginGroupId(), result);
            return result > 0;
            
        } catch (Exception e) {
            log.error("插件组绑定更新失败: agentId={}, pluginGroupId={}", request.getAgentId(), request.getPluginGroupId(), e);
            throw e;
        }
    }

    @Override
    public String getPluginTypeName(Integer pluginType) {
        if (pluginType == null) {
            return "未知";
        }
        return switch (pluginType) {
            case 1 -> "HTTP";
            case 2 -> "MCP";
            case 3 -> "内置";
            default -> "未知";
        };
    }

    @Override
    public String getPluginCategoryName(Integer pluginCategory) {
        if (pluginCategory == null) {
            return "其他";
        }
        return switch (pluginCategory) {
            case 1 -> "工具类";
            default -> "其他";
        };
    }

    @Override
    public String getPluginGroupTypeName(Integer groupType) {
        if (groupType == null) {
            return "未知";
        }
        return switch (groupType) {
            case 1 -> "工具类";
            case 2 -> "金融类";
            case 3 -> "通用能力类";
            default -> "其他";
        };
    }
}